package ch.zhaw.skuh.turing.view;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Label;
import java.awt.Panel;

import javax.swing.JTextField;

import ch.zhaw.skuh.turing.model.turingmaschine.TuringChar;

public class MaschineDetailPanel extends Panel {
	/**
	 * 
	 */
	private static final long serialVersionUID = 3540411182483585449L;
	private JTextField state, band, position, step, result, calcResult, seconds, lengthTapes;
	private JTextField[] fullBand;
	private GridBagLayout gLayout;
	private GridBagConstraints gConstraints;
	private TuringChar turingChar;

	public MaschineDetailPanel(TuringChar tc) {
		this.turingChar = tc;


		gLayout = new GridBagLayout();
		gConstraints = new GridBagConstraints();

		gConstraints.fill = GridBagConstraints.BOTH;
		gConstraints.weightx = 1.0;
		gConstraints.gridwidth = 1;

		setLayout(gLayout);

		// state
		add(getHeaderLabel("State q:"));
		state = getDataField();
		add(state);

		// band
		add(getHeaderLabel("Current Characters:"));
		band = getDataField();
		add(band);

		// position
		gConstraints.gridwidth = 1;
		add(getHeaderLabel("Positions of Heads:"));
		position = getDataField();
		add(position);

		// step
		add(getHeaderLabel("Steps:"));
		gConstraints.gridwidth = GridBagConstraints.REMAINDER; // end row
		step = getDataField();
		add(step);

		// result
		gConstraints.gridwidth = 1;
		add(getHeaderLabel("Result:"));
		result = getDataField();
		add(result);

		// calcResult
		add(getHeaderLabel("Predicted Result:"));
		calcResult = getDataField();
		add(calcResult);
		
		// time
		add(getHeaderLabel("Seconds:"));
		seconds = getDataField();
		add(seconds);
		
		//len[tapes]
		add(getHeaderLabel("Lengths:"));
		gConstraints.gridwidth = GridBagConstraints.REMAINDER; // end row
		lengthTapes = getDataField();
		add(lengthTapes );

		// fullBand
		gConstraints.gridwidth = GridBagConstraints.REMAINDER; // end row
		this.fullBand = new JTextField[turingChar.getTapeCount()];
		Dimension dim = new Dimension();
		
		for(int i=0;i<fullBand.length;i++){
			JTextField jTF = new JTextField();
			dim.setSize(jTF.getMaximumSize().getWidth(), jTF.getPreferredSize()
					.getHeight());
			jTF.setMaximumSize(dim);
			gLayout.setConstraints(jTF, gConstraints);
			fullBand[i] = jTF;
			add(fullBand[i]);
		}		

		this.setSize(this.getPreferredSize());
		this.setVisible(true);
	}
	
	public void update(long time){
		setState(turingChar.getMaschine().getState());
		setTapes(turingChar.getTapesAtCurrent());
		setPositions(turingChar.getPositions());
		setStep(turingChar.getMaschine().getSteps());
		setResult(turingChar.getResult());
		setResultPrediction(turingChar.getResultPrediction());
		setSeconds(Double.toString(time / Math.pow(10, 9)));
		StringBuilder sb = new StringBuilder(turingChar.getTapeCount());
		for(int i=0;i<turingChar.getTapeCount();i++){
			String s = turingChar.getTape(i);
			setFullTape(s, i);
			sb.append('[');
			sb.append(Integer.toString(s.length()));
			sb.append(']');
		}
		setLengthTapes(sb.toString());
		
	}

	private void setState(int state) {
		this.state.setText(Integer.toString(state));
	}

	private void setTapes(char[] tapes) {
		StringBuilder sb = new StringBuilder(tapes.length);
		for(int iTape=0;iTape<tapes.length;iTape++){
			sb.append('[');
			sb.append(tapes[iTape]);
			sb.append(']');
		}
		this.band.setText(sb.toString());
	}

	private void setPositions(int[] pos) {
		StringBuilder sb = new StringBuilder(pos.length);
		for(int iTape=0;iTape<pos.length;iTape++){
			sb.append('[');
			sb.append(Integer.toString(pos[iTape]));
			sb.append(']');
		}
		this.position.setText(sb.toString());
	}

	private void setStep(long s) {
		this.step.setText(Long.toString(s));
	}

	private void setResult(String r) {
		this.result.setText(r);
	}

	private void setResultPrediction(String cr) {
		this.calcResult.setText(cr);
	}

	private void setSeconds(String n) {
		this.seconds.setText(n);
	}

	private void setLengthTapes(String l) {
		this.lengthTapes.setText(l);
	}

	private void setFullTape(String text, int index) {
		this.fullBand[index].setText(text);
	}

	private Label getHeaderLabel(String text) {
		Label label = new Label(text, Label.RIGHT);
		label.setFont(new Font("Courier New", Font.BOLD, 16));
		label.setBackground(Color.LIGHT_GRAY);
		gLayout.setConstraints(label, gConstraints);
		return label;
	}

	private JTextField getDataField() {
		// Label label = new Label("", Label.CENTER);
		// label.setFont(new Font("Courier New", Font.PLAIN, 18));
		// label.setBackground(Color.WHITE);
		JTextField jtf = new JTextField();
		Dimension dim = new Dimension();
		dim.setSize(jtf.getMaximumSize().getWidth(), jtf.getPreferredSize()
				.getHeight());
		jtf.setMaximumSize(dim);
		jtf.setFont(new Font("Courier New", Font.PLAIN, 16));
		jtf.setBackground(Color.WHITE);
		gLayout.setConstraints(jtf, gConstraints);
		return jtf;
	}

}
